/*
 * @Description: Axios 实例配置与拦截器
 * @Version: 2.0
 * @Autor: wangmeng
 * @Date: 2021-08-03 11:13:38
 * @LastEditors: wamgmeng
 * @LastEditTime: 2024-01-18 15:11:04
 */
/* eslint-disable no-param-reassign */
import type {
	AxiosInstance,
	AxiosRequestConfig,
	InternalAxiosRequestConfig,
	AxiosResponse,
	AxiosError
} from 'axios';
import axios from 'axios';
import qs from 'qs';
import type { ResponseType } from './global.type';

// 响应状态码枚举
enum ResponseStatus {
	SUCCESS = 0,
	SUCCESS_1 = 200,
	REDIRECT = 302,
	FORBIDDEN = 400003
}

// 请求超时时间（3000秒）
const REQUEST_TIMEOUT = 3000000;

/**
 * 处理重定向逻辑
 */
const handleRedirect = (result: string): void => {
	const root = result.includes('http://') || result.includes('https://') ? '' : 'http://';

	setTimeout(() => {
		if (result.includes('serverName')) {
			window.location.href = `${root}${result}`;
		} else {
			const encodedUrl = encodeURIComponent(window.btoa(window.location.href));
			window.location.href = `${root}${result}?serverName=${encodedUrl}`;
		}
	}, 300);
};

/**
 * 创建并配置 JSON 格式的 Axios 实例
 */
const createJsonHttp = (): AxiosInstance => {
	const instance = axios.create({
		timeout: REQUEST_TIMEOUT,
		transformRequest: [
			(data: unknown): string => {
				return JSON.stringify(data);
			}
		]
	});

	// 请求拦截器
	instance.interceptors.request.use(
		(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => {
			config.headers['Content-Type'] = 'application/json';
			return config;
		},
		(error: AxiosError): Promise<AxiosError> => {
			return Promise.reject(error);
		}
	);

	// 响应拦截器
	instance.interceptors.response.use(
		<T>(response: AxiosResponse<ResponseType<T>>): Promise<T> | Promise<never> => {
			if (response.status < 400) {
				const { data } = response;
				const statusCode = data.code ?? data.status;

				// 处理重定向
				if (statusCode === ResponseStatus.REDIRECT) {
					const redirectUrl = data.result || data.message;
					if (typeof redirectUrl === 'string') {
						handleRedirect(redirectUrl);
					}
					return Promise.reject(new Error('Redirecting...'));
				}

				// 处理成功响应 - 返回 data 字段（已解包第一层 ResponseType）
				if (
					statusCode === ResponseStatus.SUCCESS ||
					statusCode === ResponseStatus.SUCCESS_1 ||
					statusCode === ResponseStatus.FORBIDDEN
				) {
					if (statusCode === ResponseStatus.SUCCESS || statusCode === ResponseStatus.SUCCESS_1) {
						return Promise.resolve(data.data);
					}
					return Promise.reject(new Error(data.message || 'Request failed'));
				}

				// 其他状态码视为错误 - 直接 reject 完整的 ResponseType
				return Promise.reject(data);
			}

			return Promise.reject(new Error(`HTTP Error: ${response.status}`));
		},
		(error: AxiosError): Promise<AxiosError> => {
			return Promise.reject(error);
		}
	);

	return instance;
};

/**
 * 创建并配置 FormData 格式的 Axios 实例
 */
const createFormDataHttp = (): AxiosInstance => {
	const instance = axios.create({
		timeout: REQUEST_TIMEOUT,
		transformRequest: [
			(data: unknown): string => {
				return qs.stringify(data);
			}
		]
	});

	// 请求拦截器
	instance.interceptors.request.use(
		(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => {
			config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
			return config;
		},
		(error: AxiosError): Promise<AxiosError> => {
			return Promise.reject(error);
		}
	);

	// 响应拦截器
	instance.interceptors.response.use(
		<T>(response: AxiosResponse<ResponseType<T>>): Promise<T> | Promise<never> => {
			if (response.status < 400) {
				const { data } = response;
				const statusCode = data.code ?? data.status;

				// 处理重定向
				if (statusCode === ResponseStatus.REDIRECT) {
					const redirectUrl = data.result || data.message;
					if (typeof redirectUrl === 'string') {
						handleRedirect(redirectUrl);
					}
					return Promise.reject(new Error('Redirecting...'));
				}

				// 处理成功响应 - 返回 data 字段（已解包第一层 ResponseType）
				if (
					statusCode === ResponseStatus.SUCCESS ||
					statusCode === ResponseStatus.SUCCESS_1 ||
					statusCode === ResponseStatus.FORBIDDEN
				) {
					if (statusCode === ResponseStatus.SUCCESS || statusCode === ResponseStatus.SUCCESS_1) {
						return Promise.resolve(data.data);
					}
					return Promise.reject(new Error(data.message || 'Request failed'));
				}

				// 其他状态码视为错误 - 直接 reject 完整的 ResponseType
				return Promise.reject(data);
			}

			return Promise.reject(new Error(`HTTP Error: ${response.status}`));
		},
		(error: AxiosError): Promise<AxiosError> => {
			return Promise.reject(error);
		}
	);

	return instance;
};

// 创建实例
const http = createJsonHttp();
const formDataHttp = createFormDataHttp();

export { http, formDataHttp };
export type { AxiosInstance, AxiosRequestConfig, AxiosResponse };
